﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace UI
{
    public delegate void UpdateTextCallback(string text);

    public delegate void EnableButton();

    public partial class RunningPleaseWait : Form
    {
        private Thread experimentsThread;
        private List<ExperimentItem> items;
        public RunningPleaseWait()
        {
            InitializeComponent();
            experimentsThread = new Thread(new ParameterizedThreadStart(runExperiments));
            experimentsThread.Start();
        }

        private void UpdateText(string text)
        {
            // Set the textbox text.
            textBox1.Text += text;
        }

        private void EnableButton ()
        {
            button2.Enabled = true;
        }


        public RunningPleaseWait(List<ExperimentItem> items)
        {
            InitializeComponent();
            this.items = items;
        }

        public void runExperiments ( Object experiments )
        {
            try
            {
                List<ExperimentItem> items = ( List<ExperimentItem>) experiments;
                for ( int i = 0; i < items.Count; i++ )
                {
                    textBox1.Invoke(new UpdateTextCallback(this.UpdateText), 
                                        new object[]{"Experiment number " + ( i + 1 ).ToString() + " out of " + items.Count + Environment.NewLine});
                    items [ i ].runExperiment();
                }
                textBox1.Invoke(new UpdateTextCallback(this.UpdateText),
                                        new object[] { "Finished successfully." + Environment.NewLine }); 
            }
            catch (ThreadAbortException ex)
            {
                textBox1.Invoke(new UpdateTextCallback(this.UpdateText),
                                        new object[] { "Aborted." + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace + Environment.NewLine });
            }
            catch (Exception ex)
            {
                textBox1.Invoke(new UpdateTextCallback(this.UpdateText),
                                        new object[] { "Error." + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace + Environment.NewLine + ex.Source + Environment.NewLine }); 
            }
            finally
            {
                button2.Invoke(new EnableButton(this.EnableButton));
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (experimentsThread.IsAlive)
                experimentsThread.Abort();
        }

        private void RunningPleaseWait_Deactivate(object sender, EventArgs e)
        {
            if (experimentsThread.IsAlive)
                experimentsThread.Abort();  
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if ( experimentsThread.IsAlive)
                experimentsThread.Abort();
            Close();
        }

        private void RunningPleaseWait_Shown(object sender, EventArgs e)
        {
            experimentsThread = new Thread(new ParameterizedThreadStart(runExperiments));
            experimentsThread.Start(items);
        }
    }
}
